package cn.quan.dlairport;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ccil.cowan.tagsoup.HTMLSchema;
import org.ccil.cowan.tagsoup.Parser;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.app.ProgressDialog;
//import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.Toast;

/**
 * 
 * @author quanyf@gmail.com 
 * 详细：通过分析网站信息获大连进出港航班信息
 */
public class DlairportActivity extends Activity {

	//view
	private ListView mListFlight=null;
	//
	private static boolean mLockLoadRemoteData=false;//防止重入
	private Map mOldData = new HashMap<String,String>();//保存前次导入数据
	public ProgressDialog mWaitDialog = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v(TAG,"onCreate");
        //view
        setContentView(R.layout.flight);
        mListFlight = (ListView)findViewById(R.id.listView1);
        
        //display
        fristUpdate();//
        //update & display
        refresh();
        
        Log.v(TAG,"onCreate end");
    }
    private void refresh(){

    	mWaitDialog = ProgressDialog.show(DlairportActivity.this, "请等候...", "后台加载数据中...");
        new Thread(){

    		@Override
    		public void run() {
    			// TODO Auto-generated method stub
    			super.run();

				//Log.v(TAG,"refresh:start");
				loadRemoteFlightData();//数据更新
				update();//更新画面
				
                //Log.v(TAG,"refresh:done");
                mWaitDialog.dismiss();
    		}
        }.start();
    	
    }
    //update remote data
    //call onCreate at once
    private void fristUpdate(){
        mLockLoadRemoteData = false;
        makeOldData();
		update();//更新画面
    }
    
    private void update(){
    	//读入csv文件，并更新画面
		hUpdate.sendEmptyMessage(1);//更新画面
    }
    Handler hUpdate = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			
			//file check
			if(!Environment.getExternalStorageState().contains("mounted")){
		        Log.v(TAG,"handler no mounted");
				return ;
			}
			String flightDir = Environment.getExternalStorageDirectory().getPath()+java.io.File.separator+FLIGHT_DIR;
			String flightFile = flightDir+java.io.File.separator+FLIGHT_FILE;
			File file = new File(flightFile);
			if(!file.exists()){
		        Log.v(TAG,"handler file not exists");
				return;
			}
			//load data in csv
			List<FlightItem> flightData = new ArrayList<FlightItem>();
			String line=null;
			FlightItem item = null;
			try {
				BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
	            while((line = br.readLine()) != null){ 
	            	item = uncomposeFlightItem(line);
	            	//set data
	            	if(item!=null){
						markRefreshData(item);//标记是否有状态更新
		            	//filter
	            		SharedPreferences filter = DlairportActivity.this.getSharedPreferences(DlairportActivity.SETTING,Activity.MODE_PRIVATE);
	            		String sFilter = filter.getString(DlairportActivity.SETTING_FILTER, "东京");
	            		if(sFilter.indexOf(item.flightFrom)>=0){
	            			flightData.add(item);
	            		}else if(sFilter.indexOf(item.flightTo)>=0){
	            			flightData.add(item);
	            		}
	            		
	            	}else{
	            		//skip
	            	}
	            }

			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			//view
			if(flightData.size()>0){
				FlightAdapter adapter = new FlightAdapter(
		        		DlairportActivity.this,
		        		R.layout.flight_list_item_3,
		        		flightData
		        		);
				mListFlight.setAdapter(adapter);
			}
			
		}
    	
    };
    //标记被更新的数据
    private void markRefreshData(FlightItem item){
		String key1 = item.flightNo+item.flightStart;
		String value1 = item.flightStartReal;
		String key2 = item.flightNo+item.flightEnd;
		String value2 = item.flightEndReal;

		String value;
		//start 
		if(mOldData.containsKey(key1)){
			value = mOldData.get(key1).toString();
			
			if(value.compareTo(value1)==0){
				item.flightStartRealRefresh=false;
			}else{
				item.flightStartRealRefresh=true;
			}
		}else{
			item.flightStartRealRefresh=false;
			
		}
		//end
		if(mOldData.containsKey(key2)){
			value = mOldData.get(key2).toString();
			if(value.compareTo(value2)==0){
				item.flightEndRealRefresh=false;
			}else{
				item.flightEndRealRefresh=true;
			}
		}else{
			item.flightEndRealRefresh=false;
			
		}
    	
    }
    //用来比较数据是否有变化
    private void makeOldData(){
		//file check
		if(!Environment.getExternalStorageState().contains("mounted")){
	        Log.v(TAG,"makeOldData no mounted");
			return ;
		}
		String flightDir = Environment.getExternalStorageDirectory().getPath()+java.io.File.separator+FLIGHT_DIR;
		String flightFile = flightDir+java.io.File.separator+FLIGHT_FILE;
		File file = new File(flightFile);
		if(!file.exists()){
	        Log.v(TAG,"makeOldData file not exists");
			return;
		}
		//load data
		String line=null;
		FlightItem item =  new FlightItem();
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            while((line = br.readLine()) != null){ 
            	
            	//set data
            	if(uncomposeFlightItem(line,item)!=null){
					
					String key1 = item.flightNo+item.flightStart;
					String value1 = item.flightStartReal;
					String key2 = item.flightNo+item.flightEnd;
					String value2 = item.flightEndReal;
					mOldData.put(key1, value1);
					mOldData.put(key2, value2);
            		
            	}else{
            		//skip
            	}
            }

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void loadRemoteFlightData(){

    	if(mLockLoadRemoteData){
            Log.v(TAG,"loadRemoteData true");
    		return;
    	}
    	
        Log.v(TAG,"loadRemoteData");
        //create file
		if(!Environment.getExternalStorageState().contains("mounted")){
	        Log.v(TAG,"loadRemoteData no mounted");
			return ;
		}
		String flightDir = Environment.getExternalStorageDirectory().getPath()+java.io.File.separator+FLIGHT_DIR;
		String flightFile = flightDir+java.io.File.separator+FLIGHT_FILE;
		
		try {
			mkdir(flightDir);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
	        Log.v(TAG,"loadRemoteData no dir");
			return ;
		}

    	//save old data
		makeOldData();
		//parse HTML 
    	mLockLoadRemoteData = true;


    	List<FlightItem> flightData = new ArrayList<FlightItem>() ;
        HttpURLConnection httpconn = null;
        URL urlAirport = null;
        final HTMLSchema schema = new HTMLSchema();
        boolean parseOK = false;
        try{

            Parser parser = new Parser();
            parser.setFeature(Parser.ignoreBogonsFeature, false);
            parser.setProperty(Parser.schemaProperty, schema);

            DlairportParserHandler handler = new DlairportParserHandler(flightData);
            parser.setContentHandler(handler);
            //parse 1
            //Log.v(TAG,"parse 1");
			urlAirport = new URL(URL_AIRPORT_INTER_IN);
            httpconn = (HttpURLConnection) urlAirport.openConnection();
            parser.parse(new InputSource(new InputStreamReader(httpconn.getInputStream())));
            //parse 2
            //Log.v(TAG,"parse 2");
			urlAirport = new URL(URL_AIRPORT_INTER_OUT);
            httpconn = (HttpURLConnection) urlAirport.openConnection();
            parser.parse(new InputSource(new InputStreamReader(httpconn.getInputStream())));
            //
            httpconn.disconnect();
            parseOK = true;
        }catch (SAXException e){
            Log.v(TAG,"parse error 1");
            e.printStackTrace();
        }catch (MalformedURLException e) {
            Log.v(TAG,"parse error 2");
        	e.printStackTrace();
        } catch (IOException e){
            Log.v(TAG,"parse error 3");
			e.printStackTrace();
		}
        if(parseOK){

	        BufferedWriter bw = null;
	        boolean createFileOK = false;
	        try {
	        	//FileOutputStream file = new FileOutputStream(flightFile, true);//path,append
				FileOutputStream file = new FileOutputStream(flightFile, false);
				bw = new BufferedWriter(new OutputStreamWriter(file, "UTF-8"));
	
				FlightItem item;
				String line;
	        	for(int i=0;i<flightData.size();i++){
	        		item = flightData.get(i);
	        		line = composeFlightItem(item);
		            bw.write(line+"\n");
	        		
	        	}
		        bw.close();
		        createFileOK = true;
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	        if(!createFileOK){
	        	mLockLoadRemoteData = false;
	        	return;
	        }
        }

        mLockLoadRemoteData = false;
        Log.v(TAG,"loadRemoteData end");

    }

	//
	//*menu
	//

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(0,0,0,"过滤");
		menu.add(0,1,0,"刷新");
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		int item_id = item.getItemId();
        //Log.v(TAG,"item id:"+item_id);
		switch(item_id){
		case 0://filter
			Intent i=new Intent(DlairportActivity.this,SettingActivity.class);
			startActivityForResult(i,LANCHED_ACTIVITY);
			break;
		case 1://update
			refresh();
	        //tRefresh.start();
			break;
		}
		return true;
	}
    @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		Log.d(TAG, "*DlairportActivity onActivityResult ");
		if(requestCode == LANCHED_ACTIVITY){
			
			update();
			if(resultCode == RESULT_OK){
				//TBD
			}
		}
	}
	//
	//*function
	//
	public static boolean mkdir(File dir) throws IOException {
		if (!dir.exists()) {
			if (!dir.mkdirs()) {
				throw new IOException("File.mkdirs() failed."); 
			}
			return true;
		} else if (!dir.isDirectory()) {
			throw new IOException("Cannot create path. " + dir.toString() + " already exists and is not a directory.");
		} else {
			return false;
		}
	}

	public static boolean mkdir(String dir) throws IOException {
		return mkdir(new File(dir));
	}
	public String composeFlightItem(FlightItem item){
		String sItem;
		sItem = item.flightNo + ",";
		sItem += item.flightFrom + ",";
		sItem += item.flightTo + ",";
		sItem += item.flightStart + ",";
		sItem += item.flightStartReal + ",";
		sItem += item.flightEnd + ",";
		sItem += item.flightEndReal + ",";
		sItem += item.flightStatus + ",";
		sItem += item.flightReason;
		return sItem;

	}
	public FlightItem uncomposeFlightItem(String line){
		String[] data=null;
    	data = line.split(",");
    	
    	
		FlightItem item =  null;
    	//set data
    	if(data.length>8){
    		item =  new FlightItem();

			item.flightNo=data[0].trim();//航班号
			item.flightFrom=data[1].trim();//始发站
			item.flightTo=data[2].trim();//目的站
			item.flightStart=data[3].trim();//预起
			item.flightStartReal=data[4].trim();//实起
			item.flightEnd=data[5].trim();//预降
			item.flightEndReal=data[6].trim();//实降
			item.flightStatus=data[7].trim();//航班状态
			item.flightReason=data[8].trim();	//延误原因	
			
    	}else{
    		//skip
    		return null;
    	}
    	return item;
	}
	public FlightItem uncomposeFlightItem(String line, FlightItem item){
		String[] data=null;
    	data = line.split(",");
    	
    	//set data
    	if(data.length>8){

			item.flightNo=data[0].trim();//航班号
			item.flightFrom=data[1].trim();//始发站
			item.flightTo=data[2].trim();//目的站
			item.flightStart=data[3].trim();//预起
			item.flightStartReal=data[4].trim();//实起
			item.flightEnd=data[5].trim();//预降
			item.flightEndReal=data[6].trim();//实降
			item.flightStatus=data[7].trim();//航班状态
			item.flightReason=data[8].trim();	//延误原因	
			
    	}else{
    		//skip
    		return null;
    	}
    	return item;
	}
	
	//
	//*static
	//
	private final static String URL_AIRPORT_INTER_IN  = "http://www.dlairport.com/wfmFreightInterIn.aspx";
	private final static String URL_AIRPORT_INTER_OUT  = "http://www.dlairport.com/wfmFreightInterOut.aspx";
	private final static String URL_AIRPORT_IN  = "http://www.dlairport.com/wfmFlightInfoIn.aspx";
	private final static String URL_AIRPORT_OUT  = "http://www.dlairport.com/wfmFlightInfoOut.aspx";
	public final static String FLIGHT_DIR = "flight";
	public final static String FLIGHT_FILE = "dalian.csv";
	public final static String SETTING="setting";
	public final static String SETTING_FILTER="filter";
	public final static String SETTING_REFRESH_STATUS="refresh";

	private final String TAG = "**FLIGHT";
	
	final int LANCHED_ACTIVITY = 2;


}